package com.yifeng.repo.apm.endpoint.logging.log4j;

import com.alibaba.fastjson.JSON;
import com.yifeng.repo.apm.endpoint.console.api.model.LogConfTypeEnum;
import com.yifeng.repo.apm.endpoint.sender.LogSender;
import com.yifeng.repo.apm.endpoint.sender.LogSenderManager;
import com.yifeng.repo.apm.endpoint.utils.BaseUtil;
import next.fire.spinus.logx.api.model.LevelEnum;
import next.fire.spinus.logx.api.model.LogData;
import next.fire.spinus.logx.utils.env.HostManager;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;

/**
 * Created by daibing on 2020/9/17
 */
public class SpinusLogxAppender extends AppenderSkeleton {
    private String appId;
    private String appStage;
    private String hostName;

    @Override
    public void activateOptions() {
        HostManager util = HostManager.get();
        appId = util.getEnvSetting("app.id", "app_id");
        appStage = util.getEnvSetting("app.stage", "app_stage");
        hostName = util.getHostName();
        LogSenderManager.startupLogSender();
    }

    @Override
    protected void append(LoggingEvent event) {
        LogSender logSender = LogSenderManager.getLogSender(true);
        if (!logSender.isLogEnabled(LogConfTypeEnum.CLOUD)) {
            return;
        }
        LocationInfo locationInformation = event.getLocationInformation();
        if (!logSender.matched(locationInformation.getClassName(), LevelEnum.get(event.getLevel().toString()))) {
            return;
        }
        LogData logData = new LogData();
        logData.setAppId(this.appId);
        logData.setStage(this.appStage);
        logData.setLevel(LevelEnum.get(event.getLevel().toString()));
        logData.setLogTime(event.getTimeStamp());
        logData.setTraceId(BaseUtil.getTraceId());
        logData.setFrontendId(BaseUtil.getFrontendId());
        logData.setHost(this.hostName);
        logData.setThread(event.getThreadName());
        logData.setLocation(locationInformation.getClassName() + ":" + locationInformation.getMethodName() + ":" + locationInformation.getLineNumber());
        String message = event.getMessage().toString();
        if (BaseUtil.isNotBlank(message)) {
            logData.setMessage(message);
        }
        logData.setThrowable(JSON.toJSONString(event.getThrowableStrRep()));
        logSender.send(logData);
    }

    @Override
    public void close() {
        LogSenderManager.shutdownSender();
    }

    @Override
    public boolean requiresLayout() {
        return false;
    }

}
